// 10-排序5 PAT Judge

#include <stdio.h>
#include <stdlib.h>

#define ElementType User
typedef struct {
    int id;
    int total;
    int perfect;
    int score[5];
    int visiable; // 是否输出
} User;

int comparator(User u1, User u2) {
    if (u1.total > u2.total) {
        return -1;
    } else if (u1.total < u2.total) {
        return 1;
    } else {
        if (u1.perfect > u2.perfect) {
            return -1;
        } else if (u1.perfect < u2.perfect) {
            return 1;
        } else {
            return u1.id - u2.id;
        }
    }
}

int qsortComparator(const void *a, const void *b) {
    return comparator(*(User *)a, *(User *)b);
}

/* sort ========================================*/
void swap(ElementType *a, ElementType *b) {
    ElementType t;
    t = *a;
    *a = *b;
    *b = t;
}

void percDown(ElementType a[], int startIdx, int length) {
    int parent, child;
    // 取出 startIdx 处存放的值
    ElementType temp = a[startIdx];
    // 向下（左右儿子）找可以正确存放 temp 的合适位置
    for (parent = startIdx; parent*2+1 < length; parent = child /* 顺着调整过的儿子节点继续向下 */) {
        child = parent*2+1;
        if ((child != length - 1) && comparator(a[child], a[child+1]) < 0) {
            // 有右儿子，且右儿子比较大
            child++; // 指向右儿子
        }
        if (comparator(temp, a[child]) >= 0) {
            // temp 比它的左右儿子都大，即找到了合适位置，不用再往下找了
            break;
        }
        // 把更大的子节点复制到父节点位置，即把大的数往上调
        a[parent] = a[child];
    }
    a[parent] = temp;
}

// 堆排序, 选择排序的一种，先建立最大堆，然后把堆顶元素和最后一个元素交换，然后把剩下的元素重新调整为最大堆，重复这个过程
void heap_Sort(ElementType a[], int length) {
    // 建立最大堆
    for (int i=length/2; i >= 0; i--) {
        percDown(a, i, length);
    }
    // 排序
    for (int i=length-1; i > 0; i--) {
        // 把堆顶元素和最后一个元素交换
        swap(&a[0], &a[i]);
        percDown(a, 0, i);
    }
}

/* current ========================================================*/
void printUsers(User users[], int n, int k) {
    int rank = 0;
    int total = -1;
    for (int i=0; i<n; i++) {
        if (users[i].visiable == 0) {
            continue;;
        }
        if (users[i].total != total) {
            rank = i + 1;
            total = users[i].total;
        }
        printf("%d %05d %d", rank, users[i].id, users[i].total);
        for (int j=0; j<k; j++) {
            if (users[i].score[j] == -2) {
                printf(" -");
            } else if (users[i].score[j] == -1) {
                printf(" 0");
            } else {
                printf(" %d", users[i].score[j]);
            }
        }
        printf("\n");
    }
}

// 初始化用户
void initUsers(User users[], int n) {
    for (int i=0; i<n; i++) {
        User *u = &users[i];
        u->id = i + 1;
        u->total = 0;
        u->perfect = 0;
        for (int p=0; p<5; p++) {
            u->score[p] = -2;
        }
        u->visiable = 0;    
    }
}

void inputUsers(User users[], int m, int perfect[]) {
    for (int i=0; i<m; i++) {
        int uid;
        int pid;
        int score;
        scanf("%d %d %d", &uid, &pid, &score);
        User *u = &users[uid-1];
        if (score > -1) {
            u->visiable = 1;
        }
        if (score > u->score[--pid]) {
            u->score[pid] = score;
        }
    }
}

// 计算总分，是否有完美提交
void calAllTotal(User users[], int n, int k, int perfect[]) {
    for (int i=0; i<n; i++) {
        User *u = &users[i];
        for (int p=0; p<k; p++) {
            if (u->score[p] < 0) {
                continue;
            }
            if (u->score[p] == perfect[p]) {
                u->perfect++;
            }
            u->total += u->score[p];
        }
    }
}

int main () {
    int n, k, m;
    scanf("%d %d %d", &n, &k, &m);
    int perfect[5];
    for (int i=0; i<k; i++) {
        scanf("%d", &perfect[i]);
    }
    User *users = calloc(n, sizeof(User));
    initUsers(users, n);
    inputUsers(users, m, perfect);
    calAllTotal(users, n, k, perfect);

    // qsort(users, n, sizeof(User), qsortComparator); 
    heap_Sort(users, n);

    printUsers(users, n, k);

    free(users);
    return 0;
}

